package net.koodar.suite.common.core.handler;

import lombok.extern.slf4j.Slf4j;
import net.koodar.suite.common.core.support.BaseResponse;
import net.koodar.suite.common.core.exception.ServiceException;
import net.koodar.suite.common.util.ExceptionUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Assert;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 控制器异常统一处理
 *
 * @author liyc
 */
@Slf4j
@RestControllerAdvice
public class ControllerExceptionHandler {

	@ResponseBody
	@ExceptionHandler(BindException.class)
	public ResponseEntity<?> paramExceptionHandler(BindException e) {
		int errorCode = HttpStatus.INTERNAL_SERVER_ERROR.value();
		List<FieldError> fieldErrors = e.getFieldErrors();
		List<String> error = fieldErrors.stream().map(field -> field.getField() + ":" + field.getDefaultMessage()).collect(Collectors.toList());
		String errorMsg = String.join(",", error);
		BaseResponse<Object> jsonResult = new BaseResponse<>(errorCode, errorMsg, error);
		return new ResponseEntity<>(jsonResult, HttpStatusCode.valueOf(jsonResult.getCode()));
	}

	@ExceptionHandler(ServiceException.class)
	public ResponseEntity<BaseResponse<Object>> handleServiceException(ServiceException e) {
		BaseResponse<Object> jsonResult = handleBaseException(e);
		jsonResult.setCode(e.getStatus().value());
		jsonResult.setData(e.getErrorData());
		return new ResponseEntity<>(jsonResult, e.getStatus());
	}

	private BaseResponse<Object> handleBaseException(Throwable t) {
		Assert.notNull(t, "Throwable must not be null");

		log.error("Captured an exception", t);

		BaseResponse<Object> jsonResult = new BaseResponse<>();
		jsonResult.setMessage(t.getMessage());
		if (log.isDebugEnabled()) {
			jsonResult.setDevMessage(ExceptionUtils.getStackTrace(t));
		}

		return jsonResult;
	}

}
